<template>
    <div class="sys-role-edit-modal relative" ref="editAddModal">
        <a-modal v-model:open="state.isShow" width="700px" wrapClassName="custom-modal"
            :bodyStyle="{ height: '500px', overflowY: 'overlay', overflowX: 'hidden', paddingRight: '6px' }"
            :title="'编辑按钮权限'" cancelText="取消" okText="确定" :getContainer="() => $refs.editAddModal" @ok="handleOk"
            @cancel="handleCancel">
            <a-table 
            :columns="columns" 
            :data-source="state.menuData" 
            :expandable="false" 
            :loading="state.loading"
            :pagination="false"
            :scroll="{ y: '400px' }">
                <template #bodyCell="{ column, record }">
                    <template v-if="column.key === 'title'">
                        <span>{{ record.title }}</span>
                        <a-button class="ml-2" type="primary" size="small" @click="onClickAllCheck(record)">
                            {{ record.checkAll ? '取消' : '全选' }}
                        </a-button>
                    </template>
                    <template v-else-if="column.key === 'btns'">
                    <div class="btn-list-scrollable">
                        <a-checkbox-group 
                            :options="record.btns" 
                            :ref="(el:any) => setCheckGroups(el, record.id)"
                            @change="(checkedValues:any[]) => handleCheckGroupChange(record.id, checkedValues)">
                            <template #label="{ label }">
                                <span>{{ label }}</span>
                            </template>
                        </a-checkbox-group>
                    </div>
                </template>
                </template>
            </a-table>
        </a-modal>
    </div>
</template>

<script setup lang="ts">
import { reactive, onMounted, ref, nextTick } from 'vue';
import type { FormInstance } from 'ant-design-vue';
import { apiSysMenuListGet } from '@/api/sys/sysMenu';
import type { ResType } from '@/api/types';
import { apiSysRoleAddPost, apiSysRoleOwnBtnMenuListGet, apiSysRoleOwnMenuListGet, apiSysRoleUpdatePost, apiUpdateRoleBtnMenuPost } from '@/api/sys/sysRole';
import type { TreeProps } from 'ant-design-vue';
import { clone, cloneDeep } from 'lodash';
import { emitter, showMsg } from '@/utils';
import { Loading } from '@element-plus/icons-vue';

const emits = defineEmits<{
    (e: "handleQuery"): void
}>()
const formRef = ref<FormInstance>()
const editAddModal = ref()

const checkGroups = ref<any>({})
const setCheckGroups = (el: Element, id: string) => {
    checkGroups.value[id] = el
}

const state = reactive({
    isShow: false,
    formState: {} as any,
    menuData: [] as any,
    menuDataOrigin: [] as any[],
    expandedKeys: [] as TreeProps['treeData'],
    selectedKeys: [] as TreeProps['selectedKeys'],
    checkedKeys: [] as any[],
    checkedBtnIds: {} as Record<string, string[]>, // 存储每个菜单下选中的按钮ID
    expandedRows: [] as string[], // 存储展开的行ID
    loading: true,
    checkStrictly: false,
    btnIds: [] as any[],
})

const columns: any[] = [
    {
        title: '菜单名称',
        dataIndex: 'title',
        key: 'title',
        width: 180,
        align: 'center',
        fixed: 'left',
    },
    {
        title: '按钮',
        key: 'btns',
        align: 'center',
    },
]

const handleOk = async () => {
    try{
        state.loading = true
        await formRef.value?.validate()
        const submitData = cloneDeep(state.formState)
        const checkedBtnIds = Object.keys(checkGroups.value).map(key => checkGroups.value[key].mergedValue).flat()
        submitData.menuIdList = checkedBtnIds
        // 该组件只走更新
        if (state.formState.id != undefined && state.formState.id > 0) {
            await apiUpdateRoleBtnMenuPost(submitData)
            showMsg('修改成功', 'success')
        }
        handleCancel()
        emits('handleQuery')
        emitter.emit('posOrRoleUpdate') //更新用户列表缓存
    }finally{
        state.loading = false
    }
}

const handleCancel = async () => {
    state.isShow = false
    state.formState = {}
    state.menuData = []
    state.expandedKeys = []
    state.selectedKeys = []
    state.checkedKeys = []
    state.checkedBtnIds = {}
    state.expandedRows = []
    state.btnIds = []
}

const handleCheckGroupChange = (menuId: string, checkedValues: string[]) => {
    // 找到对应的菜单记录
    const menuItem = state.menuData.find((item: any) => item.id === menuId);
    if (!menuItem) return;
    
    // 检查当前菜单下的所有按钮是否都被选中
    const allBtnIds = menuItem.btns.map((btn: any) => btn.id);
    const allChecked = allBtnIds.length > 0 && allBtnIds.every((id:any) => checkedValues.includes(id));
    
    // 更新菜单的checkAll状态
    menuItem.checkAll = allChecked;
};

// 过滤菜单和按钮，保留包含按钮的菜单树结构
const formateMenuBtnData = (data: any[]) => {
    const cloneData = cloneDeep(data);

    const filterMenuWithButtons = (items: any[]): any[] => {
        // 第一步：找出所有包含按钮的菜单(type=2)
        const menuItemsWithButtons: any[] = [];

        const findMenuWithButtons = (nodes: any[]) => {
            nodes.forEach(node => {
                // 如果是菜单(type=2)且包含按钮子项，将其加入结果
                if (node.type === 2 && Array.isArray(node.children)) {
                    const hasButtons = node.children.some((child: any) => child.type === 3);
                    if (hasButtons) {
                        // 只保留该菜单及其按钮子项，过滤掉其他类型的子项
                        const menuWithButtons = { ...node };
                        menuWithButtons.children = node.children.filter((child: any) => child.type === 3);
                        menuItemsWithButtons.push(menuWithButtons);
                    }
                }
                // 继续递归搜索子节点
                if (Array.isArray(node.children) && node.children.length > 0) {
                    findMenuWithButtons(node.children);
                }
                if (node.children.length == 0) {
                    delete node.children
                }
            });
        };

        // 执行搜索
        findMenuWithButtons(items);

        menuItemsWithButtons.forEach(item => {
            item.btns = item.children.map((btn: any) => {
                return {
                    ...btn,
                    label: btn.title,
                    value: btn.id
                }
            })
            // 初始化checkAll状态为false
            item.checkAll = false;
            delete item.children
        })
        state.btnIds = menuItemsWithButtons.flatMap(item => item.btns.map((btn: any) => btn.id))
        return menuItemsWithButtons;
    };
    const filteredData = filterMenuWithButtons(cloneData);

    return filteredData
};

// 过滤出按钮id
const filterMapCheckedIds = (data: any[]) => {
    let ids: any[] = []
    data.forEach(id => {
        if (state.btnIds.findIndex(item => item == id) != -1) {
            ids.push(id)
        }
    })
    return ids
}

const handleOpen = async (row?: any) => {
    state.isShow = true
    state.loading = true
    // 获取所有菜单展示
    let res = await apiSysMenuListGet({ tenantId: row.tenantId }) as ResType<any>
    state.menuDataOrigin = res.data.result ?? []
    state.menuData = formateMenuBtnData(state.menuDataOrigin)
    state.formState = JSON.parse(JSON.stringify(row))
    if (row.id != undefined) {
        // 获取当前角色拥有的按钮权限
        res = await apiSysRoleOwnBtnMenuListGet(row.id)
        state.checkedKeys = filterMapCheckedIds(res.data.result)
        nextTick(() => {
            // 给每一个单独的多选组进行赋值
            Object.keys(checkGroups.value).forEach(key => {
                state.menuData.forEach((item: any) => {
                    if (key == item.id) {
                        let curMenu: any = item
                        const menuBtnIds = curMenu.btns.map((btn: any) => btn.id);
                        const checkedBtnIds = menuBtnIds.filter((id:any) => state.checkedKeys.includes(id));
                        
                        // 设置选中的按钮
                        if (checkedBtnIds.length > 0) {
                            checkGroups.value[key].mergedValue.push(...checkedBtnIds);
                        }
                        
                        // 检查是否所有按钮都被选中，并设置checkAll状态
                        item.checkAll = menuBtnIds.length > 0 && checkedBtnIds.length === menuBtnIds.length;
                    }
                })
            })
        })
    }
    state.loading = false
    formRef.value?.clearValidate()
}

const onClickAllCheck = (record: any) => {
    const menuId = record.id;
    const menuItem = state.menuData.find((item: any) => item.id === menuId);
    if (!menuItem || !checkGroups.value[menuId]) return;
    
    // 切换全选状态
    const newCheckAllState = !menuItem.checkAll;
    menuItem.checkAll = newCheckAllState;
    
    // 更新checkbox group的选中状态
    if (newCheckAllState) {
        // 全选：选中当前菜单下所有按钮
        const allBtnIds = menuItem.btns.map((btn: any) => btn.id);
        // 清空现有选中项并添加所有按钮ID
        checkGroups.value[menuId].mergedValue = [...allBtnIds];
    } else {
        // 取消全选：清空当前菜单下所有按钮选中状态
        checkGroups.value[menuId].mergedValue = [];
    }
}

defineExpose({
    handleOpen
})
</script>

<style lang="scss" scoped>
:deep(.ant-form-item) {
    margin-bottom: 20px;
}

:deep(.anticon.anticon-caret-down) {
    display: inline-flex;
}

:deep(.ant-tree-checkbox) {
    margin-block-start: 0;
}

/* 按钮权限水平滚动容器 */
.btn-list-scrollable {
    /* 重要：确保容器不会挤压其他列 */
    min-width: 0;
    overflow: visible;
}

/* 修复Ant Design表格列宽度问题 */
:deep(.ant-table-cell) {
    overflow: visible !important;
}

/* 按钮组容器 - 这是真正滚动的元素 */
:deep(.ant-checkbox-group) {
    display: inline-flex;
    flex-wrap: nowrap;
    gap: 12px;
    padding: 4px 0;
    max-width: 400px;
    /* 限制最大宽度，确保滚动条出现 */
    overflow-x: auto;
    user-select: none;

    /* 隐藏滚动条但保留滚动功能 */
    &::-webkit-scrollbar {
        height: 4px;
    }

    &::-webkit-scrollbar-track {
        background: #f1f1f1;
        border-radius: 2px;
    }

    &::-webkit-scrollbar-thumb {
        background: #ccc;
        border-radius: 2px;
    }

    &::-webkit-scrollbar-thumb:hover {
        background: #999;
    }
}

:deep(.ant-checkbox-wrapper) {
    margin-right: 0;
    margin-bottom: 0;
}
</style>